package com.joycessh.search.index.util;

import com.joycessh.search.index.entity.Page;
import com.joycessh.search.index.entity.PageInfo;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.highlight.*;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.nutch.indexwriter.song.SongConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.wltea.analyzer.lucene.IKAnalyzer;
import org.wltea.analyzer.lucene.IKAnalyzer4Lucene7;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author Joycessh
 * @Description
 * @Date 5/3/19 2:54 PM
 */
public class IndexReaderUtil {
    private static final Logger LOG = LoggerFactory.getLogger(IndexReaderUtil.class);

    public volatile static IndexReader instance;

    public static String directoryPath = "/opt/tmp/index";

    public static IndexReader getInstance() throws IOException {
        if (instance != null) {

        }else {
            synchronized (IndexReader.class) {
                if (instance == null) {

                    //创建索引存放目录，文件系统
                    Directory directory = FSDirectory.open((new File(directoryPath)).toPath());
//                    Directory directory = IndexWriterUtil.getInstance().getDirectory();
                    // 索引读取工具
                    instance = DirectoryReader.open(directory);
                    LOG.info("索引读取工具IndexReader创建完成");
                }
            }
        }
        return instance;
    }

    public static PageInfo executeQuery(int pageNum, int pageSize, Query query) throws IOException, InvalidTokenOffsetsException {

        List<Page> list = new ArrayList<Page>();

        int start = (pageNum - 1) * pageSize;// 当前页的起始条数
        int end = start + pageSize;// 当前页的结束条数（不能包含）

        IndexReader indexReader = IndexReaderUtil.getInstance();
        // 创建搜索工具
        IndexSearcher searcher = new IndexSearcher(indexReader);
        LOG.info("创建搜索工具: " + searcher);

        //获取搜索的结果，指定返回document返回的个数
        TopDocs topDocs = searcher.search(query, end);
        LOG.info("本次搜索共" + topDocs.totalHits + "条数据");
        if (topDocs.totalHits == 0) {
            return null;
        }

        //最终被分词后添加的前缀和后缀处理器，默认是粗体<B></B>
        Formatter htmlFormatter = new SimpleHTMLFormatter("<em>","</em>");
        //高亮搜索的词添加到高亮处理器中
        Highlighter highlighter = new Highlighter(htmlFormatter, new QueryScorer(query));

        //创建分词器
        Analyzer analyzer = new IKAnalyzer4Lucene7();


        ScoreDoc[] scoreDocs = topDocs.scoreDocs;

        for (int i = start; i < scoreDocs.length; i++) {
            ScoreDoc scoreDoc = scoreDocs[i];
            int docID = scoreDoc.doc;
            Document doc = indexReader.document(docID);

            Page page = new Page();
            page.setDocID(docID);
            page.setScore(scoreDoc.score);

            page.setUrl(doc.get("tstamp"));
            String anchor = doc.get("anchor");
            if (anchor != null) {
                page.setAnchor(anchor);
            }
            page.setDigest(doc.get("digest"));
            page.setHost(doc.get("host"));
            page.setBoost(doc.get("boost"));
            page.setId(doc.get("id"));
            page.setUrl(doc.get("url"));

            // 内容增加高亮显示
            String title = doc.get("title");
            if (title != null) {
                TokenStream tokenStream1 = analyzer.tokenStream("title", new StringReader(title));
                String hTitle = highlighter.getBestFragment(tokenStream1, title);
                page.setTitle(hTitle);
            }
            String content = new StringBuffer(doc.get("content").substring(0, 100)).append("...").toString();
            if (content != null) {
                TokenStream tokenStream1 = analyzer.tokenStream("title", new StringReader(content));
                String hContent = highlighter.getBestFragment(tokenStream1, content);
                page.setContent(hContent);
            }
            list.add(page);
        }

        StringBuffer sb = new StringBuffer("分页信息\n");
        sb.append("\t").append("pageNum: ")
                .append(pageNum + "\n");
        sb.append("\t").append("pageSize: ")
                .append(pageSize + "\n");
        sb.append("\t").append("total: ")
                .append((scoreDocs.length - start) + "\n");
        sb.append("\t").append("result: ")
                .append(list.toString() + "\n");

        LOG.info(sb.toString());

        PageInfo<Page> pageInfo = new PageInfo();
        pageInfo.setData(list);
        pageInfo.setPageNum(pageNum);
        pageInfo.setPageSize(pageSize);
        pageInfo.setTotal(topDocs.totalHits);
        pageInfo.setSize(scoreDocs.length - start);
        return pageInfo;
    }
}
